/* combined.c
 * Test Program to test wait/signal/broadcast functionalities for the systemcall
 */

#include "syscall.h"
int lockNumber1,cvNumber1,threadsWaiting=0;
int threadID=0;
void testfunc()
{
	int myID;
	Acquire(lockNumber1);
	myID=threadID;
	threadID=threadID+1;
	Print2("Thread : %d is waiting on lockId : %d \n",myID,lockNumber1);
	threadsWaiting=threadsWaiting+1;
	Wait(cvNumber1,lockNumber1);
	Print1("Thread %d Coming Out of Wait\n",myID);
	Release(lockNumber1);
	Exit(0);

}
void testfunc1()
{
	int myID;
	Acquire(lockNumber1);
	myID=threadID;
	threadID=threadID+1;
	Print1("Thread : %d to send Signal\n",myID);
	Signal(cvNumber1,lockNumber1);
	threadsWaiting=threadsWaiting-1;
	Release(lockNumber1);
	Exit(0);

}
void testfunc2()
{
	int myID;
	Acquire(lockNumber1);
	myID=threadID;
	threadID=threadID+1;
	Print2("Thread : %d to send Broadcast to %d more waiting threads\n",myID,threadsWaiting);
	Broadcast(cvNumber1,lockNumber1);
	Release(lockNumber1);
	Exit(0);

}

void main()
{
  	lockNumber1=CreateLock("lock1",5);
	cvNumber1=CreateCondition("cond1",5);

	Print("Forking three threads will go on wait, 1 more thread signals a waiting thread and another thread will broadcast remaining two waiting threads\n");
	Fork(testfunc);
	Fork(testfunc);
	Fork(testfunc);
	Yield();
	Fork(testfunc1);
	Yield();
	Yield();
	Yield();
	Yield();
	Yield();
	Fork(testfunc2);

	Exit(0);
}
